/**
  Returns list of codes: a comma separated string of the LZW compression decimal numbers (the last code must be 0)
  symbols: sorted string of valid data symbols for the text. The index will be the code of the intial dictionary
  stop: The last symbol of the text
  text: Uncompressed text: text is made of combinations of symbols. The stop symbol appears once and at the end of the text
*/
function encode(symbols, stop, text) {
  var dict = {}
  for (var i = 0; i < symbols.length; i++)dict[symbols[i]] = i;
  var last = symbols.length;
  var codes = [];
  var a = ''
  for (b of text) {
    key = a + b
    if (dict[key]) {
      a = key;
    } else {
      if (dict[a]) codes.push(dict[a])
      dict[key] = last++;
      a = b;
    }
    if (b === stop) {
      codes.push(0);
      break;
    }
  }
  return codes.join(',')
}

/**
  Returns a uncompressed text given a sequence of compressed codes
  symbols: Valid data symbols
  code: string of comma separated codes. The last code always will be 0
*/
function decode(symbols, code) {
  var dict = symbols.split('');
  var codes = code.split(',')
  var p = codes.shift();
  var a = dict[p];
  var res = a;
  for (c of codes) {
    var entry = ''
    if (+c >= dict.length) {
      entry = a + a[0];
    } else {
      entry = dict[+c];
    }
    res += entry;
    dict.push(a + entry[0]);
    a = entry;
  }
  return res
}
var symbols = '#ABCDEFGHIJKLMNOPQRSTUVWXYZ'
var text = 'TOBEORNOTTOBEORTOBEORNOT#';
var code = undefined
console.log(encode(symbols, '#', text))



